// import the packages
import {
  Injectable,
  EventEmitter
} from '@angular/core';

import { HubConnectionBuilder, HubConnection } from "@aspnet/signalr";
import { environment } from 'environments/environment';
import { HttpService } from '../..';
import { ChatGroup, ChatInfo } from '../model/User';
@Injectable()
export class SignalRService {
  // Declare the variables
  private connection: HubConnection;
  // create the Event Emitter
  public messageReceived: EventEmitter<any>;
  public chatrole: EventEmitter<any>;
  public connectionEstablished: EventEmitter<Boolean>;
  public startDrill: EventEmitter<any>;
  public goToDrill = new EventEmitter<number>();
  public goToNextStep = new EventEmitter<any>();
  public connectionExists: Boolean;
  public UserChatContext = new Array<ChatGroup>();
  constructor(
    private httpService: HttpService
  ) {
    const myThis = this;
    // Constructor initialization
    this.connectionEstablished = new EventEmitter<Boolean>();
    this.messageReceived = new EventEmitter<any>();
    this.chatrole = new EventEmitter<any>(); // 聊天订阅内容
    this.startDrill = new EventEmitter<any>();
    this.connectionExists = false;
    // create hub connection
    this.connection = new HubConnectionBuilder()
      .withUrl(`${httpService.IP_PORT}/GameHallHub`)
      .build();
    this.registerOnServerEvents();
    // call the connecion start method to start the connection to send and receive events.
    // this.startConnection();

    this.connection.onclose(e => {
      myThis.connectionExists = false;
      myThis.startConnection();
    });
  }

  public startConnection(): void {
    if (!this.connectionExists) {
      this.connection.start().then(e => {
        this.connectionEstablished.emit(true);
        this.connectionExists = true;
      }).catch((error: any) => {
        console.log('Could not connect ' + error);
        this.connectionEstablished.emit(false);
      });
    }
  }
  private registerOnServerEvents(): void {
    this.connection.on("refresh", (personId, recordId) => {
      this.messageReceived.emit({ personId: personId, recordId: recordId });
    });
    // 接收服务端信息传给页面
    this.connection.on("chatrole", (senderId, message) => {
      this.chatrole.emit({ senderId: senderId, message: message });
    });

    this.connection.on("start", () => {
      this.startDrill.emit();
    });

    this.connection.on("goToDrill", (recordId) => {
      this.goToDrill.emit(recordId);
    });

    this.connection.on("goNextStep", (recordId) => {
      this.goToNextStep.emit(recordId);
    });
  }

  public JoinRoom(recordId: string): Promise<any> {
    return this.connection.invoke("JoinRoom", recordId).catch(err => console.error(err.toString()));
  }

  public SelectRole(recordId: string, personId: string): Promise<any> {
    return this.connection.invoke("SelectRole", recordId, personId).catch(err => console.error(err.toString()));
  }

  public Start(recordId: string): Promise<any> {
    return this.connection.invoke("StartDrill", recordId).catch(err => console.error(err.toString()));
  }

  public RgisterUser(userId: string) {
    return this.connection.invoke("RgisterUser", userId).catch(err => console.error(err.toString()));
  }

  public CallTheNextPerson(recordId: string) {
    return this.connection.invoke("CallTheNextPerson", recordId).catch(err => console.error(err.toString()));
  }

  public Chat(senderId, message: string): Promise<any> {
    return this.connection.invoke("Chat", senderId, message).catch(err => console.error(err.toString()));
  }

  public async IniChatContext() {
    if (sessionStorage.getItem('userRoleType') === "2" || sessionStorage.getItem('userRoleType') === "3") {
      this.UserChatContext = await this.httpService.get<Array<ChatGroup>>("StudentInfo/GetClassInfoToStudentById?searchName=");
      this.chatrole.subscribe(content => {
        this.UserChatContext.forEach(gp => {
          gp.chatUsers.forEach(findCu => {
            if (findCu.id.toString() === content.senderId.toString()) {
              if (!findCu.chatInfos) {
                findCu.chatInfos = new Array<ChatInfo>();
              }
              findCu.chatInfos.push(new ChatInfo(findCu.id, findCu.personName, content.message));
            }
          });
        });
      });
    }
  }

  public GetMessage() {
    let result = 0;
    this.UserChatContext.forEach(gp => {
      gp.chatUsers.forEach(findCu => {
        if (findCu.chatInfos && findCu.chatInfos.length > 0) {
          result += findCu.chatInfos.filter(cis => !cis.isRead).length;
        }
      });
    });
    return result;
  }

  public GetMessageCount(groupId: number, userId: number) {
    let result = 0;
    const arGroup = this.UserChatContext.filter(e => e.id === groupId);
    arGroup.forEach(gp => {
      gp.chatUsers.forEach(findCu => {
        if (findCu.chatInfos && findCu.chatInfos.length > 0) {
          result += findCu.chatInfos.filter(cis => !cis.isRead && (userId > 0 ? cis.id === userId : true)).length;
        }
      });
    });
    return result;
  }

  public AddMessage(groupId: number, userId: number, msg: string, name: string) {
    const arGroup = this.UserChatContext.filter(e => e.id === groupId);
    arGroup.forEach(gp => {
      gp.chatUsers.forEach(findCu => {
        if (findCu.id === userId) {
          if (!findCu.chatInfos) {
            findCu.chatInfos = new Array<ChatInfo>();
          }
          findCu.chatInfos.push(new ChatInfo(0, name, msg, true));
        }
      });
    });
  }
}
